package top.psjj.mall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.zxing.WriterException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.psjj.mall.comment.Constant;
import top.psjj.mall.exception.MallException;
import top.psjj.mall.exception.MallExceptionEnum;
import top.psjj.mall.filter.UserFilter;
import top.psjj.mall.mapper.CartMapper;
import top.psjj.mall.mapper.OrderItemMapper;
import top.psjj.mall.mapper.OrderMapper;
import top.psjj.mall.mapper.ProductMapper;
import top.psjj.mall.model.dto.CreateOrderReq;
import top.psjj.mall.model.po.Order;
import top.psjj.mall.model.po.OrderItem;
import top.psjj.mall.model.po.Product;
import top.psjj.mall.model.vo.CartVo;
import top.psjj.mall.model.vo.OrderItemVo;
import top.psjj.mall.model.vo.OrderVo;
import top.psjj.mall.service.api.CartService;
import top.psjj.mall.service.api.OrderService;
import top.psjj.mall.utils.OrderCodeFactory;
import top.psjj.mall.utils.QRCodeGenerator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private CartService cartService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private CartMapper cartMapper;
    @Value("${upload_dir}")
    private String dir;
    @Override
    public String createOrder(Integer userId, CreateOrderReq createOrderReq) {
        //获得购物车已勾选的数据
        List<CartVo> list = cartService.list(userId);
        List<CartVo> tempList = new ArrayList<CartVo>();
        for (CartVo cartVo : list){
            if(cartVo.getSelected().equals(Constant.CartSelected.SELECTED)){
                tempList.add(cartVo);
            }
        }
        list = tempList;
        //是否为空
        if(CollectionUtils.isEmpty(list)){
            throw new MallException(MallExceptionEnum.CART_IS_EMPTY);
        }
        //校验数据合法性
        validSelectedCarts(list);
        //将数据转化为订单项数据
        List<OrderItem> orderItemList = cartVoListToOrderItemList(list);
        //扣除数据库库存
        delStock(orderItemList);
        //清除购物车中数据
        clearCartSelected(list);
        //生成订单
        String orderNo = OrderCodeFactory.getOrderCode(userId.longValue());
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setOrderStatus(Constant.OrderStatusEnum.NOT_PAID.getCode());
        order.setPaymentType(1);
        order.setPostage(0);
        order.setReceiverName(createOrderReq.getReceiverName());
        order.setReceiverMobile(createOrderReq.getReceiverMobile());
        order.setReceiverAddress(createOrderReq.getReceiverAddress());
        order.setUserId(userId);
        order.setTotalPrice(getOrderTotalPrice(orderItemList));
        orderMapper.insertSelective(order);
        //插入订单项数据
        for (OrderItem orderItem : orderItemList){
            orderItem.setOrderNo(orderNo);
            orderItemMapper.insertSelective(orderItem);
        }
        return orderNo;
    }

    @Override
    public OrderVo detail(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if(order==null){
            throw new MallException(MallExceptionEnum.NOT_ORDER);
        }
        if(!order.getUserId().equals(UserFilter.currentUser.getId())){
            throw new MallException(MallExceptionEnum.ORDER_NOT_YOUR);
        }
        OrderVo orderVo = getOrderVoByOrder(order);
        return orderVo;
    }

    @Override
    public PageInfo listForCustomer(Integer pageNum, Integer pageSize) {
        //开启分页
        PageHelper.startPage(pageNum,pageSize);
        //查询数据
        List<Order> orders = orderMapper.selectOrdersByUserId(UserFilter.currentUser.getId());
        //转vo
        List<OrderVo> orderVos = getOrderVosByOrders(orders);
        //构建分页
        PageInfo pageInfo = new PageInfo(orders);
        pageInfo.setList(orderVos);
        return pageInfo;
    }

    @Override
    public void cancel(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NOT_ORDER);
        }
        if(!order.getUserId().equals(UserFilter.currentUser.getId())){
            throw new MallException(MallExceptionEnum.ORDER_NOT_YOUR);
        }
        if(!order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
            throw new MallException(MallExceptionEnum.WRONG_ORDER_STATUS);
        }else {
            Order o = new Order();
            o.setId(order.getId());
            o.setOrderNo(orderNo);
            o.setOrderStatus(Constant.OrderStatusEnum.CANCELED.getCode());
            o.setEndTime(new Date());
            orderMapper.updateByPrimaryKeySelective(o);
        }


    }

    @Override
    public String qrcode(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        String QrPng = createQRCodeByOrder(order);
        return QrPng;
    }

    @Override
    public void pay(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NOT_ORDER);
        }
        if(!order.getUserId().equals(UserFilter.currentUser.getId())){
            throw new MallException(MallExceptionEnum.ORDER_NOT_YOUR);
        }
        if (order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
            Order o = new Order();
            o.setId(order.getId());
            o.setOrderNo(order.getOrderNo());
            o.setOrderStatus(Constant.OrderStatusEnum.PAID.getCode());
            o.setPayTime(new Date());
            orderMapper.updateByPrimaryKeySelective(o);
        }else {
            throw new MallException(MallExceptionEnum.WRONG_ORDER_STATUS);
        }
    }

    @Override
    public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
        //开启分页
        PageHelper.startPage(pageNum,pageSize);
        List<Order> orders = orderMapper.selectOrderAll();
        List<OrderVo> orderVos = getOrderVosByOrders(orders);
        PageInfo pageInfo = new PageInfo(orders);
        pageInfo.setList(orderVos);
        return pageInfo;
    }

    @Override
    public void deliver(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NOT_ORDER);
        }
        if (order.getOrderStatus().equals(Constant.OrderStatusEnum.PAID.getCode())){
            Order o = new Order();
            o.setId(order.getId());
            o.setOrderNo(orderNo);
            o.setOrderStatus(Constant.OrderStatusEnum.DELIVERED.getCode());
            o.setDeliveryTime(new Date());
            orderMapper.updateByPrimaryKeySelective(o);
        }else {
            throw new MallException(MallExceptionEnum.WRONG_ORDER_STATUS);
        }
    }

    @Override
    public void finish(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if(order==null){
            throw  new MallException(MallExceptionEnum.NOT_ORDER);
        }
        if (UserFilter.currentUser.getRole().equals(Constant.User.IS_USER) && !UserFilter.currentUser.getId().equals(order.getUserId())){
            throw  new MallException(MallExceptionEnum.ORDER_NOT_YOUR);
        }
        if(order.getOrderStatus().equals(Constant.OrderStatusEnum.DELIVERED.getCode())){
            Order o = new Order();
            o.setId(order.getId());
            o.setOrderNo(orderNo);
            o.setOrderStatus(Constant.OrderStatusEnum.FINISHED.getCode());
            o.setEndTime(new Date());
            orderMapper.updateByPrimaryKeySelective(o);
        }else {
            throw new MallException(MallExceptionEnum.WRONG_ORDER_STATUS);
        }
    }

    private String createQRCodeByOrder(Order order) {
        try {
            QRCodeGenerator.generateQRCodeImage("http://支付路径",350,350,dir+"temp.png");
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "http://127.0.0.1/images/temp.png";
    }

    private List<OrderVo> getOrderVosByOrders(List<Order> orders) {
        List<OrderVo> orderVos = new ArrayList<OrderVo>();
        for (Order order : orders){
            OrderVo orderVo = getOrderVoByOrder(order);
            orderVos.add(orderVo);
        }
        return orderVos;
    }

    //封装订单Vo
    private OrderVo getOrderVoByOrder(Order order) {
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order,orderVo);
        List<OrderItemVo> orderItemVoList = new ArrayList<OrderItemVo>();
        List<OrderItem> orderItemList = orderItemMapper.selectByOrderNo(order.getOrderNo());
        for (OrderItem orderItem : orderItemList){
            OrderItemVo orderItemVo = new OrderItemVo();
            BeanUtils.copyProperties(orderItem,orderItemVo);
            orderItemVoList.add(orderItemVo);
        }
        orderVo.setOrderItemVoList(orderItemVoList);
        orderVo.setOrderStatusName(Constant.OrderStatusEnum.NOT_PAID.getValue());
        return orderVo;
    }

    //计算商品总价
    private Integer getOrderTotalPrice(List<OrderItem> orderItemList) {
        int orderTotal = 0;
        for (OrderItem orderItem : orderItemList){
            orderTotal+=orderItem.getTotalPrice();
        }
        return orderTotal;
    }

    private void clearCartSelected(List<CartVo> list) {
        for (CartVo cartVo : list){
            cartMapper.deleteByPrimaryKey(cartVo.getId());
        }
    }

    private void delStock(List<OrderItem> orderItemList) {
        for (OrderItem orderItem : orderItemList){
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            product.setStock(product.getStock()-orderItem.getQuantity());
            productMapper.updateByPrimaryKeySelective(product);
        }
    }

    private List<OrderItem> cartVoListToOrderItemList(List<CartVo> list) {
        List<OrderItem> orderItemList = new ArrayList<OrderItem>();
        for (CartVo cartVo : list){
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(cartVo.getProductId());
            orderItem.setQuantity(cartVo.getQuantity());
            orderItem.setProductImg(cartVo.getProductImage());
            orderItem.setTotalPrice(cartVo.getTotalPrice());
            orderItem.setProductName(cartVo.getProductName());
            orderItem.setUnitPrice(cartVo.getPrice());
            orderItemList.add(orderItem);
        }
        return orderItemList;
    }

    private void validSelectedCarts(List<CartVo> list) {
        for (CartVo cartVo : list){
            Product product = productMapper.selectByPrimaryKey(cartVo.getProductId());
            if(product == null || product.getStatus().equals(Constant.SellStatus.NOT_SELL)){
                throw new MallException(MallExceptionEnum.NOT_SELL);
            }
            if (product.getStock()<cartVo.getQuantity()){
                throw new MallException(MallExceptionEnum.NEED_STOCK);
            }
        }
    }

}
